package com.hongdee.crm.taskConfig.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.hongdee.common.util.TokenUtil;
import com.hongdee.crm.Constant;
import com.hongdee.crm.taskConfig.dao.ITCrmTaskTypeRefDao;
import com.hongdee.crm.taskConfig.entity.TCrmTaskTypeRef;
import com.hongdee.crm.taskConfig.service.ITCrmTaskTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by My on 2017/3/6.
 */
@Service
public class TCrmTaskTypeServiceImpl implements ITCrmTaskTypeService {
    @Autowired
    private ITCrmTaskTypeRefDao itCrmTaskTypeRefDao;
    private String tabName = "T_CRM_TASK_TYPE_REF";
    private String tableRole = "T_BC_ROLE";
    private String tableParamSet = "T_BC_PARAM_SET";
    private String entity = "TCrmTaskTypeRef";

    /**
     * @param data
     * @return Map
     * @throws Exception
     * @desc 任务类型分配
     * @author 徐钦勇
     */
    @Override
    public void saveOrUpdate(Map data, String uid) throws Exception {
        String oid = TokenUtil.getCompanyId(uid);
        String sql = "delete from " + tabName + " where task_code = ? and company_id = ?  and type = ? ";
        List l = new ArrayList();
        l.add(data.get("taskCode"));
        l.add(oid);
        l.add(data.get("type"));
        this.itCrmTaskTypeRefDao.executeSQL(sql, l.toArray());
        List<String> tempList = (List<String>) data.get("roleId");
        //当插入数据为处理角色时
        // 每个任务类型只能存在一个处理角色
        if (String.valueOf(data.get("type")).equals("1")) {
            if (tempList.size() == 1) {
                for (String id : tempList) {

                    TCrmTaskTypeRef entity = new TCrmTaskTypeRef();
                    entity.setId(null);
                    entity.setStatus("1");
                    entity.setCompanyId(oid);
                    entity.setRoleId(id);
                    entity.setTaskCode(String.valueOf(data.get("taskCode")));
                    entity.setType(String.valueOf(data.get("type")));
                    this.itCrmTaskTypeRefDao.saveOrUpdate(entity);
                }
            } else {
                throw new Exception("每个任务类型只能存在一个处理角色！");
            }
        }
        //当插入数据为查看角色时
        if (String.valueOf(data.get("type")).equals("0")) {
            for (String id : tempList) {
                //每个任务类型可存多个角色
                TCrmTaskTypeRef entity = new TCrmTaskTypeRef();
                entity.setId(null);
                entity.setStatus("1");
                entity.setCompanyId(oid);
                entity.setRoleId(id);
                entity.setTaskCode(String.valueOf(data.get("taskCode")));
                entity.setType(String.valueOf(data.get("type")));
                this.itCrmTaskTypeRefDao.saveOrUpdate(entity);
            }
        }
    }

    /**
     * @param id     主键
     * @param status 状态
     * @return Map
     * @throws Exception
     * @desc 启用停用
     * @author 徐钦勇
     */
    @Override
    public void update(String id, String status) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择记录");
        }
        String hql = "update " + entity + " set status = :status where id = :id ";
        Map params = new HashMap();
        params.put("id", id);
        params.put("status", status);
        this.itCrmTaskTypeRefDao.update(hql, params);
    }

    /**
     * @param
     * @return List
     * @throws Exception
     * @desc 角色下拉列表
     * @author 徐钦勇
     */
    @Override
    public List<Map> comboRole(String companyId) throws Exception {
        String sql = " select * from " + tableRole + " where r_status ='1' and o_id = ? ";
        List param = new ArrayList();
        param.add(companyId);
        List<Map<String, Object>> mapList = this.itCrmTaskTypeRefDao.list(sql, param.toArray());
        List<Map> resList = new ArrayList<Map>();
        Map temp;
        for (Map map : mapList) {
            temp = new HashMap();
            temp.put("value", map.get("id"));
            temp.put("label", map.get("rName"));
            resList.add(temp);
        }
        return resList;
    }


    /**
     * 根据公司获得角色，并填充角色的查看任务权限、处理任务权限
     *
     * @param uid
     * @return
     * @throws Exception
     */
    @Override
    public List<Map> comboRoleList(String uid) throws Exception {
        //获取当前人员部门
        String oId = TokenUtil.getDeptId(uid);
        String companyId = TokenUtil.getCompanyId(uid);
        List params = new ArrayList();
        //查询所有角色，公司，是否应用下级部门
        String resSql = "select * from t_bc_role where r_status='1' ";
        if (!"0".equals(oId)) {
            List<Map<String, Object>> resList = this.itCrmTaskTypeRefDao.list(resSql, params.toArray());
            List list = new ArrayList();
            resSql += " and ( id in ( ";
            for (Map resMap : resList) {
                //判断是否应用下级
                switch (resMap.get("hasChild").toString()) {

                    //未应用下级，判断是否是当前部门相同
                    case "0": {
                        //当前部门与查询已有部门一致
                        if (oId.equals(resMap.get("oId").toString())) {
                            resSql += " ?, ";
                            params.add(resMap.get("id").toString());
                        }
                    }
                    break;
                    //应用下级，判断下级部门及当前公司是否与本公司相同
                    case "1": {
                        //登录者所有上级部门及公司
                        list = parent(oId, list);
                        int i = 0;
                        for (Object obj : list) {
                            //判断本部门是否在上级部门及公司里
                            if (obj.toString().equals(resMap.get("oId").toString())) {
                                i++;
                            }
                        }
                        //本部门在上级部门及公司内
                        if (i > 0) {
                            resSql += " ?, ";
                            params.add(resMap.get("id").toString());
                        }
                    }
                    break;
                }
            }
            resSql += " '' ) or o_id = ? ) ";
        }
       params.add(companyId);
        List<Map<String, Object>> mapList = this.itCrmTaskTypeRefDao.list(resSql, params.toArray());

        List<Map> resList = new ArrayList<Map>();
        Map temp;
        for (Map map : mapList) {
            temp = new HashMap();
            String roleId = String.valueOf(map.get("id"));
            temp.put("value", map.get("id"));
            temp.put("label", map.get("rName"));
            String seeNames = this.findRoleTaskType(String.valueOf(Constant.TASKPOWER.SEE.ordinal()), companyId, roleId);
            String handleNames = this.findRoleTaskType(String.valueOf(Constant.TASKPOWER.HANDLE.ordinal()), companyId, roleId);
            temp.put("seeNames", seeNames);
            temp.put("handleNames", handleNames);
            resList.add(temp);
        }
        return resList;
    }

    private String findRoleTaskType(String type, String companyId, String roleId) throws Exception {
        String sql = "select GROUP_CONCAT(t.`name`) typeName from ( " +
                "SELECT ref.task_code, ref.type, ref.role_id, ref.company_id, def.`name` FROM " +
                "t_crm_task_type_ref ref, " +
                "t_bc_param_def def " +
                "WHERE ref.task_code = def. CODE AND ref.type = ?  AND " +
                "ref.role_id=? " +
                "AND ref.company_id=? " +
                "GROUP BY ref.task_code) t GROUP BY t.role_id";
        Map<String, Object> map = this.itCrmTaskTypeRefDao.info(sql, type, roleId, companyId);
        if (map != null) {
            if (map.size() > 0) {
                return String.valueOf(map.get("typeName"));
            }
        }
        return "";
    }


    /**
     * @param
     * @return List
     * @throws Exception
     * @desc 任务类型下拉列表
     * @author 徐钦勇
     */
    @Override
    public List<Map> comboTask(String companyId) throws Exception {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT                                 ");
        sql.append("	p_code, CASE p_code                ");
        sql.append("WHEN 'by' THEN                         ");
        sql.append("	'保养'                             ");
        sql.append("WHEN 'bx' THEN                         ");
        sql.append("	'保险'                             ");
        sql.append("WHEN 'ga' THEN                         ");
        sql.append("	'关爱'                             ");
        sql.append("WHEN 'ls' THEN                         ");
        sql.append("	'流失'                             ");
        sql.append("END p_name                             ");
        sql.append("FROM " + tableParamSet + "                ");
        sql.append("WHERE                                  ");
        sql.append("	company_id = ?                   ");
        sql.append("AND p_code IN ('by', 'bx', 'ga', 'ls') ");
        sql.append("GROUP BY  p_code                       ");
        List param = new ArrayList();
        param.add(companyId);
        List<Map<String, Object>> mapList = this.itCrmTaskTypeRefDao.list(sql.toString(), param.toArray());
        List<Map> resList = new ArrayList<Map>();
        Map temp;
        for (Map map : mapList) {
            temp = new HashMap();
            temp.put("value", map.get("pCode"));
            temp.put("label", map.get("pName"));
            resList.add(temp);
        }
        return resList;
    }

    /**
     * @param start     当前页面
     * @param limit     页面大小
     * @param companyId
     * @return Map
     * @throws Exception
     * @desc 分页查询
     * @author 徐钦勇
     */
    @Override
    public Map page(String start, String limit, String companyId, String taskType) throws Exception {
        String sql = "select tt.*,tr.r_name from " + tabName + " tt left join t_bc_role tr on tt.role_id=tr.id where tt.company_id = ? ";
        List params = new ArrayList();
        params.add(companyId);
        if (!taskType.isEmpty()) {
            sql += " and tt.task_code = ? ";
            params.add(taskType);
        }
        return this.itCrmTaskTypeRefDao.page(sql, params.toArray(), start, limit);
    }

    /**
     * @param id 主键
     * @return Map
     * @throws Exception
     * @desc 任务类型分配详情
     * @author 徐钦勇
     */
    @Override
    public List info(String oid, String id) throws Exception {
        if (org.springframework.util.StringUtils.isEmpty(id)) {
            throw new Exception("请选择记录");
        }
        String sql = "select task_code from " + tabName + " where id = ? and company_id = ? ";
        List params = new ArrayList();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        List l = new ArrayList();
        params.add(id);
        params.add(oid);
        list = this.itCrmTaskTypeRefDao.list(sql, params.toArray());
        for (Map map : list) {
            l.add(map.get("taskCode"));
        }
        return l;
    }


    /**
     * 查询角色下取得已选择中的参数节点
     *
     * @param companyId 公司信息
     * @param roleId    角色ID
     * @return List<Object>
     * @throws Exception
     */
    @Override
    public List<Object> checkedDefSee(String companyId, String roleId) throws Exception {
        String sqlStr = " " +
                "select role_id, task_code from t_crm_task_type_ref where " +
                "company_id = ?  and role_id =? and type='0' ";
        List<Map<String, Object>> lsMp = this.itCrmTaskTypeRefDao.list(sqlStr, companyId, roleId);
        List<Object> temp = new ArrayList<>();
        for (Map<String, Object> mp : lsMp) {
            temp.add(mp.get("taskCode"));
        }
        return temp;
    }

    /**
     * 处理权限获得其已经选择的角色节点
     *
     * @param companyId
     * @param roleId
     * @return
     * @throws Exception
     */
    @Override
    public List<Object> checkedDefCheck(String companyId, String roleId) throws Exception {
        String sqlStr = "" +
                "select role_id, task_code from t_crm_task_type_ref where " +
                "company_id = ?  and role_id =? and type='1' ";
        List<Map<String, Object>> lsMp = this.itCrmTaskTypeRefDao.list(sqlStr, companyId, roleId);
        List<Object> temp = new ArrayList<>();
        for (Map<String, Object> mp : lsMp) {
            temp.add(mp.get("taskCode"));
        }
        return temp;
    }

    /**
     * 处理权限获得其它角色已经选择的节点
     *
     * @param companyId
     * @param roleId
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, List<Object>>> checkedDefRonly(String companyId, String roleId) throws Exception {
        List<Map<String, List<Object>>> lists = new ArrayList<>();
        String sqlROnly = "" +
                "select role_id, task_code from t_crm_task_type_ref where " +
                "company_id = ?  and role_id <> ? and type='1'";
        List<Map<String, Object>> lsMpROnly = this.itCrmTaskTypeRefDao.list(sqlROnly, companyId, roleId);
        List<Object> tempROnly = new ArrayList<>();
        for (Map<String, Object> mp : lsMpROnly) {
            tempROnly.add(mp.get("taskCode"));
        }
        Map<String, List<Object>> rOnlyMap = new HashMap<>();
        rOnlyMap.put("ronly", tempROnly);
        lists.add(rOnlyMap);
        return lists;
    }

    /**
     * 保存查看或处理权限选择的任务处理信息
     *
     * @param list
     * @param roleId
     * @param companyId
     * @param type
     * @throws Exception
     */
    @Override
    public void saveTaskType(List<String> list, String roleId, String companyId, String type) throws Exception {
        List<TCrmTaskTypeRef> typeRefs = new ArrayList<>();
        if (list.size() > 0) {
            //遍历已经勾选的节点信息,只获得参数信息
            List<Map<String, Object>> treeNodeMaps = this.getParamsNode(list);
            for (Map<String, Object> map : treeNodeMaps) {
                String pCode = String.valueOf(map.get("pCode"));
                TCrmTaskTypeRef typeRef = new TCrmTaskTypeRef();
                typeRef.setTaskCode(pCode);
                typeRef.setRoleId(roleId);
                typeRef.setCompanyId(companyId);
                typeRef.setStatus("1");
                typeRef.setType(type);
                typeRefs.add(typeRef);
            }
        }
        itCrmTaskTypeRefDao.executeSQL("delete from t_crm_task_type_ref where company_id=? and role_id=? and type=?", companyId, roleId, type);
        if (typeRefs.size() > 0) {
            itCrmTaskTypeRefDao.saveOrUpdateList(typeRefs);
        }
    }

    /**
     * 获得选择的节点信息
     *
     * @param list
     * @return
     * @throws Exception
     */
    private List<Map<String, Object>> getParamsNode(List<String> list) throws Exception {
        StringBuffer sql = new StringBuffer();
        List<String> params = new ArrayList<>();
        sql.append("select id,code,name,p_code from t_bc_param_def where type ='1' and p_code in (");
        for (int i = 0; i < list.size(); i++) {
            String code = list.get(i);
            sql.append("?");
            params.add(code);
            if (i < list.size() - 1) {
                sql.append(",");
            }
        }
        sql.append(") group by p_code   ");
        List<Map<String, Object>> defMap = itCrmTaskTypeRefDao.list(sql.toString(), params.toArray());
        return defMap;
    }


    /**
     * 查询参数树
     *
     * @param pCode 上级节点编码
     * @return
     */
    @Override
    public List tree(String roleId, String pCode, String companyId, String type) throws Exception {
        return buildParamChild(roleId, pCode, companyId, false, type);
    }

    /***
     * 查询任务定认参数值
     * @param pCode 默认为任务类型
     * @return
     */
    @Override
    public List treeParam(String roleId, String pCode, String companyId, String type) throws Exception {
        return buildParamChild(roleId, pCode, companyId, true, type);
    }

    private List buildParamChild(String roleId, String pCode, String companyId, boolean hasParam, String type) throws Exception {
        //从缓存中取得用户已有的角色
        if (type.equals(String.valueOf(Constant.TASKPOWER.SEE.ordinal()))) {
            return this.taskSee(roleId, pCode, companyId, hasParam, type);
        } else {
            return this.taskHandle(roleId, pCode, companyId, hasParam, type);
        }
    }

    private List taskSee(String roleId, String pCode, String companyId, boolean hasParam, String type) throws Exception {
        //从缓存中取得用户已有的角色

        String sqlStr = " select * from t_bc_param_def where p_code = ? ";
        if (!hasParam) {
            sqlStr += " and type != '1' ";
        }
        List<Map<String, Object>> treeP = this.itCrmTaskTypeRefDao.list(sqlStr, pCode);
        return buildParamParent(treeP, roleId, companyId, hasParam, type);
    }

    private List taskHandle(String roleId, String pCode, String companyId, boolean hasParam, String type) throws Exception {
        String sqlStr = " SELECT * from t_bc_param_def def " +
                "WHERE NOT EXISTS (" +
                "SELECT * FROM " +
                "t_crm_task_type_ref " +
                "WHERE " +
                "role_id <> ? " +
                "AND company_id = ? " +
                "AND type = ? " +
                "AND def. CODE = task_code ) ";
        if (!hasParam) {
            sqlStr += " and def.type != '1' ";
        }
        sqlStr += "and def.p_code=? ";
        List<Map<String, Object>> treeP = this.itCrmTaskTypeRefDao.list(sqlStr, roleId, companyId, type, pCode);
        return buildParamParent(treeP, roleId, companyId, hasParam, type);
    }

    private List buildParamParent(List<Map<String, Object>> paramList, String roleId, String companyId, boolean hasParam, String type) throws Exception {
        if (paramList.size() == 0) {
            return paramList;
        }
        List<Map<String, Object>> childList;
        for (Map map : paramList) {
            String resId = String.valueOf(map.get("code"));
            childList = buildParamChild(roleId, resId, companyId, hasParam, type);
            //存在子节点，增加子节点 返回
            map.put("child", childList);
        }
        return paramList;
    }

    /****
     * 查询上一层次的部门
     */
    String ORG_PARENT_SQL = " select o_p_id from t_bc_organ where id = ? ";
    private List parent(String oid, List resIds) throws Exception {
        Map temp = this.itCrmTaskTypeRefDao.info(ORG_PARENT_SQL, oid);
        if (temp == null || temp.size() == 0) {
            return resIds;
        } else {
            oid = String.valueOf(temp.get("oPId"));
            resIds.add(oid);
            return parent(oid, resIds);
        }
    }
}
